package pl.ydp.utils
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.geom.Matrix;
	import flash.utils.ByteArray;
	
	import mx.graphics.codec.JPEGEncoder;
	import mx.graphics.codec.PNGEncoder;
	
	/**
	 * Screenshot utility class. Suports capturing PNG,JPG,BMP and BitmapData from any DisplayObject.
	 */ 
	
	public class ScreenCaptureUtil
	{
		
		/**
		 * Class contructor
		 */
		public function ScreenCaptureUtil()
		{
		}
		
		
		/**
		 * Method for capturing BitmapData from DisplayObject.
		 * Set 'width' & 'height' parameter to 0 if you want to use original 'source' dimensions.
		 * If only one size paramater is greater then '0' then the other one will be fitted proportionally 
		 * (acpect ratio will be maintained)
		 * @param source screenshot data source
		 * @param width generated BitmapData width
		 * @param height generated BitmapData height
		 * @param keepRatio if set to 'true' acpect ratio will be maintained  
		 * @return generated screenshot   
		 */
		public static function getBitmapDataFrom( source:DisplayObject, width:int=0, height:int=0, keepRatio:Boolean = true ):BitmapData
		{		
			
			var sourceWidth:Number = ( source.width > 2880 )? 2880 : source.width;
			var sourceHeight:Number = ( source.height > 2880 )? 2880 : source.height; 
			sourceWidth = sourceWidth==0 ? 1 : sourceWidth;
			sourceHeight = sourceHeight==0 ? 1 :sourceHeight;				
			
			var bitmapData:BitmapData = 
				new BitmapData ( 
					sourceWidth,
					sourceHeight );
			
			if ( !width && !height ){
				 bitmapData.draw( source );
			}
			else {	
				
				var scaleWidth:Number = width / sourceWidth;
	      		var scaleHeight:Number = height / sourceHeight;
				var scaleMatrix:Matrix = new Matrix();
				
				if ( !width || !height ){
					( !scaleHeight ) ? scaleHeight = scaleWidth : scaleWidth = scaleHeight;
					
					scaleMatrix.scale( scaleWidth, scaleWidth );
					height = sourceHeight*scaleWidth;
					width = sourceWidth*scaleWidth;
					
				}
				else {
					scaleWidth = width / sourceWidth;
	      			scaleHeight = height / sourceHeight;
					
					if ( keepRatio ){
						if ( scaleWidth < scaleHeight )
						{
							scaleMatrix.scale( scaleWidth, scaleWidth ); 
							height = sourceHeight*scaleWidth; 
						}
						else 
						{
							scaleMatrix.scale( scaleHeight, scaleHeight );
							width = sourceWidth*scaleHeight;
						}
					}else {
						scaleMatrix.scale( scaleWidth, scaleHeight );
					}
				}
				
				
				width = width<1 ? 1 : width;
				height = height<1 ? 1 : height;
				bitmapData = new BitmapData ( width, height );
				bitmapData.draw(source,scaleMatrix,null,null,null,true);
			}

																	
			return bitmapData;
			
		}
		
		/**
		 * Method for capturing Bitmap from DisplayObject.
		 * Set 'width' & 'height' parameter to 0 if you want to use original 'source' dimensions.
		 * If only one size paramater is greater then '0' then the other one will be fitted proportionally 
		 * (acpect ratio will be maintained)
		 * @param source screenshot data source
		 * @param width generated Bitmap width
		 * @param height generated Bitmap height
		 * @param keepRatio if set to 'true' acpect ratio will be maintained  
		 * @return generated screenshot   
		 */
		
		public static function getBitmapFrom( source:DisplayObject,
										 width:int=0, height:int=0, keepRatio:Boolean = true ):Bitmap
		{
			return new Bitmap ( getBitmapDataFrom(source, width , height, keepRatio) );
		}
		
		/**
		 * Method for capturing JPG from DisplayObject.
		 * Set 'width' & 'height' parameter to 0 if you want to use original 'source' dimensions.
		 * If only one size paramater is greater then '0' then the other one will be fitted proportionally 
		 * (acpect ratio will be maintained)
		 * @param source screenshot data source
		 * @param width generated JPG width
		 * @param height generated JPG height
		 * @param keepRatio if set to 'true' acpect ratio will be maintained  
		 * @return generated screenshot   
		 */
		
		public static function getJPGFrom( source:DisplayObject, 
										width:int=0, height:int=0, keepRatio:Boolean = true ):ByteArray
		{
			return new JPEGEncoder().encode( getBitmapDataFrom (source, width , height, keepRatio) ) ;
		}
		
		
		
		/**
		 * Method for capturing PNG from DisplayObject.
		 * Set 'width' & 'height' parameter to 0 if you want to use original 'source' dimensions.
		 * If only one size paramater is greater then '0' then the other one will be fitted proportionally 
		 * (acpect ratio will be maintained)
		 * @param source screenshot data source
		 * @param width generated PNG width
		 * @param height generated PNG height
		 * @param keepRatio if set to 'true' acpect ratio will be maintained  
		 * @return generated screenshot   
		 */
		
		public static function getPNGFrom( source:DisplayObject, 
										width:int=0, height:int=0, keepRatio:Boolean = true ):ByteArray
		{
			return new PNGEncoder().encode( getBitmapDataFrom (source, width , height, keepRatio) ) ;
		}
		
		 
		 /**
		 * Method allows to resize passed BitmapData to new dimensions.
		 * @param source screenshot data source
		 * @param width new width
		 * @param height new height
		 * @param keepRatio if set to 'true' acpect ratio will be maintained  
		 * @return resized BitmapData   
		 */
		public static function resizeBitmapData( sourceBitmapData:BitmapData, 
												width:int, height:int, keepRatio:Boolean = true):BitmapData
		{		
			
			var scaleWidth:Number = width / sourceBitmapData.width;
      		var scaleHeight:Number = height / sourceBitmapData.height;
			var scaleMatrix:Matrix = new Matrix();
			
			if ( keepRatio )
			{
				if ( scaleWidth < scaleHeight )
				{
					scaleMatrix.scale( scaleWidth, scaleWidth ); 
					height = sourceBitmapData.height*scaleWidth; 
				}
				else 
				{
					scaleMatrix.scale( scaleHeight, scaleHeight );
					width = sourceBitmapData.width*scaleHeight;
				}
			}		
			
			
			var resized:BitmapData = new BitmapData ( width, height, true );
			resized.draw(sourceBitmapData,scaleMatrix,null,null,null,true);
						
			return resized;			
			
		}
	}
}